NOTE: please knit the
calculations.Rmd
notebook first to prepare the data used here.
# load experiments info
experiments <- readxl::read_excel(file.path("data", "experiments.xlsx"))
# load strains info
strains <- readxl::read_excel(file.path("data", "strains.xlsx"))
# load concentration data
conc_data_w_t0 <- read_rds(file.path("cache", "conc_data_w_t0.rds"))
# load isotope data
iso_data_w_t0 <- read_rds(file.path("cache", "iso_data_w_t0.rds"))
# load growth data
growth_data <- readxl::read_excel(file.path("data", "data.xlsx"), sheet = "growth_data")
# load growth rates data
growth_rates_data <- read_rds(file.path("cache", "growth_rates_data.rds"))
# fractionation factors
eps_data <- read_rds(file.path("cache", "eps_data.rds"))
# fractionationc coupling
coupling_data <- read_rds(file.path("cache", "coupling_data.rds"))
# prepare data
all_data <-
experiments %>%
left_join(strains, by = c("strain_id")) %>%
right_join(eps_data, by = c("exp_id")) %>%
left_join(coupling_data, by = c("strain_id", "medium")) %>%
left_join(growth_rates_data, by = c("exp_id", "culture")) %>%
arrange(name, medium, exp_id, culture) %>%
transmute(
Species = name,
`Reductase genes` = nitrate_reductases,
Medium = medium,
Tracer = enriched_water,
`18eps / 15eps` = sprintf("%.2f +/- %.2f", ON_ratio, ON_ratio_se),
`15eps` = sprintf("%.1f +/- %.1f", eps15N.permil, eps15N_se.permil),
`18eps` = sprintf("%.1f +/- %.1f", eps18O.permil, eps18O_se.permil),
`Growth rate (1/hour)` = ifelse(!is.na(mu.1_hr), sprintf("%.2f +/- %.2f", mu.1_hr, mu_se.1_hr), NA),
)
# save table
all_data %>%
mutate(
same_species = c("DNE", head(Species, -1)) == Species,
same_medium = same_species & c("DNE", head(Medium, -1)) == Medium,
same_tracer = c("DNE", head(Tracer, -1)) == Tracer,
Species = ifelse(same_species, NA_character_, Species),
`Reductase genes` = ifelse(same_species, NA_character_, `Reductase genes`),
Medium = case_when(
same_medium & same_tracer ~ NA_character_,
Tracer == "yes" ~ paste(Medium, "+", "18O water"),
TRUE ~ Medium
),
`18eps / 15eps` = ifelse(same_medium, NA_character_, `18eps / 15eps`)
) %>%
select(-Tracer, -starts_with("same_")) %>%
export_to_excel(file = file.path("tables", "table_S1.xlsx"))
all_data
# experiment and strain info combined
exp_strains <-
experiments %>%
left_join(
select(strains, strain_id, name, nitrate_reductases),
by = c("strain_id")
) %>%
mutate(
name = str_replace(name, "\U0394", "$\\\\Delta$"),
panel = sprintf("%s (%s)", name, medium) %>% factor(),
medium = paste("Medium:", medium),
)
# generate plot template for most of the SI plots
base_plot <-
ggplot() +
aes(color = as.factor(culture), shape = enriched_water) +
facet_wrap(~panel, ncol = 3, scales = "free", labeller = latex_labeller, drop = FALSE) +
theme_figure(text_size = 16, strip_text_size = 10) +
scale_color_manual(values = cb_palette) +
labs(color = "Culture", shape = latex2exp::TeX("$^{18}$O water added?"))
# prepare data frame for plotting
ps1_data <-
growth_data %>%
left_join(exp_strains, by = c("exp_id"))
ps1_fit <-
growth_rates_data %>%
left_join(exp_strains, by = c("exp_id")) %>%
generate_logistic_curve(
time = hour, N = OD, N0 = OD0,
time_min = hour_min, time_max = hour_max,
K = K, r = mu.1_hr
)
# generate plot
ps1 <-
base_plot %+%
ps1_data %+%
aes(x = hour, y = OD) +
# fit
geom_line(
data = ps1_fit,
mapping = aes(shape = NULL, group = paste(exp_id, culture))
) +
# data
geom_point(size = 3) +
# labels
labs(x = "Time (hours)", y = "OD")
ps1
# prepare data frame for plotting
ps2_data <-
left_join(conc_data_w_t0, iso_data_w_t0, by = c("exp_id", "culture", "timepoint")) %>%
left_join(exp_strains, by = c("exp_id")) %>%
mutate(NO2.mM = ifelse(is.na(NO2.mM), 0, NO2.mM)) %>%
pivot_longer(c(NO3.mM, NO2.mM), names_to = "var", values_to = "val") %>%
filter(!is.na(hour), !is.na(val)) %>%
mutate(
conc = factor(var) %>% fct_rev() %>% fct_recode(
"$NO_2^-$ (mM)" = "NO2.mM",
"$NO_3^-$ (mM)" = "NO3.mM"
)
)
# generate plot
ps2 <-
base_plot %+%
ps2_data %+%
aes(x = hour, y = val, linetype = conc) +
# data
geom_line() +
geom_point(size = 3) +
# star IC purified data points
geom_text(
data = function(df)
filter(df, var == "NO2.mM", str_detect(treatment, fixed("IC"))) %>%
mutate(label = "*"),
mapping = aes(label = label), size = 8, color = "black",
hjust = 0.5, vjust = 0.5, nudge_x = -1, nudge_y = -0.5
) +
# scales and labels
scale_linetype_manual(values = c(1, 2), labels = latex_labeller) +
labs(x = "Time (hours)", y = "Concentration", linetype = "Concentration")
ps2
# prepare data frame for plotting (all cultures with more than 2 data points)
ps3_4_data <-
inner_join(conc_data_w_t0, iso_data_w_t0, by = c("exp_id", "culture", "timepoint")) %>%
left_join(exp_strains, by = c("exp_id")) %>%
group_by(exp_id, culture) %>% filter(n() > 2L) %>% ungroup()
# generate plot
ps3 <-
base_plot %+%
ps3_4_data %+%
aes(x = ln_NO3, y = D_d15N) +
# linear regression fits
geom_smooth(method = lm, formula = y ~ x, se = FALSE) +
# data
geom_point(size = 3) +
# star IC purified data points
geom_text(
data = function(df)
filter(df, str_detect(treatment, fixed("IC"))) %>%
mutate(label = "*"),
mapping = aes(label = label), size = 8, color = "black",
hjust = 0.5, vjust = 0.5, nudge_x = -0.1, nudge_y = -0.5
) +
# scales and labels
scale_x_reverse() +
labs(
x = latex2exp::TeX("ln(\\[NO_3^-\\] / \\[NO_3^-\\]_{initial})$"),
y = latex2exp::TeX("$\\Delta \\delta^{15}N$ of $NO_3^-$")
)
ps3
# generate plot
ps4 <-
base_plot %+%
ps3_4_data %+% # same data as in fig. S3
aes(x = ln_NO3, y = D_d18O) +
# linear regression fits
geom_smooth(method = lm, formula = y ~ x, se = FALSE) +
# data
geom_point(size = 3) +
# star IC purified data points
geom_text(
data = function(df)
filter(df, str_detect(treatment, fixed("IC"))) %>%
mutate(label = "*"),
mapping = aes(label = label), size = 8, color = "black",
hjust = 0.5, vjust = 0.5, nudge_x = -0.1, nudge_y = -0.5
) +
# scales and labels
scale_x_reverse() +
labs(
x = latex2exp::TeX("ln(\\[NO_3^-\\] / \\[NO_3^-\\]_{initial})$"),
y = latex2exp::TeX("$\\Delta \\delta^{18}O$ of $NO_3^-$")
)
ps4
# prepare data frame for plotting
ps5_data <-
iso_data_w_t0 %>%
left_join(exp_strains, by = c("exp_id"))
# generate plot
ps5 <-
base_plot %+%
ps5_data %+%
aes(x = D_d15N, y = D_d18O) +
# 0.5 and 1.0 reference lines
geom_abline(
data = tibble(
icept = 0, slope = c(1, 0.5),
line = sprintf("%.1f", slope) %>% factor() %>% fct_inorder()
),
mapping = aes(
x = NULL, y = NULL, color = NULL, shape = NULL,
intercept = icept, slope = slope, linetype = line
)
) +
# linear regression fits
geom_smooth(
mapping = aes(color = NULL, shape = NULL),
method = lm, formula = y ~ x, se = FALSE, color = "red",
show.legend = FALSE
) +
# data
geom_point(size = 3) +
# star IC purified data points
geom_text(
data = function(df)
filter(df, str_detect(treatment, fixed("IC"))) %>% mutate(label = "*"),
mapping = aes(label = label), size = 8, color = "black",
hjust = 0.5, vjust = 0.5, nudge_x = -1.5, nudge_y = -0.5
) +
# scales and labels
labs(
x = latex2exp::TeX("$\\Delta \\delta^{15}N$ of $NO_3^-$"),
y = latex2exp::TeX("$\\Delta \\delta^{18}O$ of $NO_3^-$"),
linetype = latex2exp::TeX("$\\frac{^{18}\\epsilon}{^{15}\\epsilon}$ ratio")
) +
guides(color = guide_legend(override.aes = list(linetype = 0)))
ps5
# prepare data frame for plotting
ps6_data <-
iso_data_w_t0 %>%
left_join(exp_strains, by = c("exp_id")) %>%
filter(enriched_water == "yes") %>%
mutate(
panel = name %>% fct_drop() %>% { fct_relevel(., levels(.)[c(2,4,3,1)]) }
)
# generate plot
ps6 <-
base_plot %+%
ps6_data %+%
aes(
x = D_d15N, y = D_d18O,
color = nitrate_reductases, shape = nitrate_reductases
) +
# 0.5 and 1.0 reference lines
geom_abline(
data = tibble(
icept = 0, slope = c(1, 0.5),
line = sprintf("%.1f", slope) %>% factor() %>% fct_inorder()
),
mapping = aes(
x = NULL, y = NULL, color = NULL, shape = NULL,
intercept = icept, slope = slope, linetype = line
)
) +
# data
geom_point(size = 4, alpha = 0.9) +
# scales and labels
scale_shape_manual(values = c(15, 17, 16)) +
scale_colour_manual(
values = c("#660099", "#0066CC", "#CC0000")
) +
labs(
x = latex2exp::TeX("$\\Delta \\delta^{15}N$ of $NO_3^-$"),
y = latex2exp::TeX("$\\Delta \\delta^{18}O$ of $NO_3^-$"),
linetype = latex2exp::TeX("$\\frac{^{18}\\epsilon}{^{15}\\epsilon}$ ratio"),
color = "reductases", shape = "reductases"
) +
guides(color = guide_legend(override.aes = list(linetype = 0)))
ps6